using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using NPMonitor.DataModel;
using NPMonitor.Helpers;
using NPMonitor.Implementation;

namespace NPMonitor.Web.UserControls
{
    public partial class ScheduleJobInfo : BaseUserControl
    {
        #region Properties

        protected string JobId
        {
            get { return this.Request.QueryString["jobid"]; }
        }

        protected string PoolId
        {
            get { return this.Request.QueryString["poolId"]; }
        }

        protected string WorkflowId
        {
            get { return this.Request.QueryString["workflowId"]; }
        }

        #endregion

        #region Method

        protected override void OnPreRender(EventArgs e)
        {
            cvDesc.ErrorMessage = string.Format(ValidationString.FieldLengthExceeded, "Description", "1000");
            cvMachineName.ErrorMessage = string.Format(ValidationString.FieldRequired, "Machine");
            cvTimeOut.ErrorMessage = string.Format(ValidationString.FieldInvalid, "Time Out (e.g.:00:00:00)");
            rvJobName.ErrorMessage = string.Format(ValidationString.FieldRequired, "Job");
            rvMachinePool.ErrorMessage = string.Format(ValidationString.FieldRequired, "Pool");
            rvWorkflowName.ErrorMessage = string.Format(ValidationString.FieldRequired, "Workflow");
            cvRetryTimes.ErrorMessage = string.Format(ValidationString.FieldRequired, "Retry Times (must larger than zero! )");
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ResetData();

                ResetViewMode();

                if (PoolId != null || (JobId == null && PoolId == null && WorkflowId == null))
                {
                    hfFromJobOrMachine.Value = "default.aspx";

                    SetViewMode("SelectItem");
                }
                else if (JobId != null)
                {
                    hfFromJobOrMachine.Value = "jobmanagement.aspx";

                    SetViewMode("Job");
                }
                else if (WorkflowId != null)
                {
                    hfFromJobOrMachine.Value = "WorkflowManagement.aspx";

                    SetViewMode("Workflow");
                }

                BindJobName();

                BindWorkFlow();

                BindMachinePool();
            }
        }

        protected void ddlMachinePoolList_SelectedIndexChanged(object sender, EventArgs e)
        {
            var machinePoolList = StoreManager.Current.MachineStore.GetAllMachinePool().ToList();

            string poolName = ddlMachinePoolList.Text;

            if (!string.IsNullOrWhiteSpace(poolName))
            {
                divPoolMachineList.Visible = true;

                var pool = machinePoolList.Find(x => x.PoolName == poolName);

                var machineInSpecPool = StoreManager.Current.MachineStore.GetMachinesByPoolId(pool.PoolId);

                var machineConnectted = machineInSpecPool.Where(x => x.Connectivity == CommonString.MachineConnected).ToList();

                rpMachineList.DataSource = machineInSpecPool;

                rpMachineList.DataBind();

                for (int i = 0; i < rpMachineList.Items.Count; i++)
                {
                    CheckBox machine = rpMachineList.Items[i].FindControl("chkIsSelected") as CheckBox;

                    Label lblMachineName = rpMachineList.Items[i].FindControl("lblMachineName") as Label;

                    machine.Checked = false;

                    foreach (var item in machineConnectted)
                    {
                        if (lblMachineName.Text == item.MachineName)
                        {
                            machine.Checked = true;
                        }
                    }
                }
            }
            else
            {
                divPoolMachineList.Visible = false;
            }
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            List<JobData> jobDataList = new List<JobData>();

            int jobId, workflowId;

            int.TryParse(ddlJobNameList.SelectedValue, out jobId);

            int.TryParse(ddlWorkflowList.SelectedValue, out workflowId);

            var jobToCheck = StoreManager.Current.JobDefinitionStore.GetJobDefinitionById(jobId);

            var workflowToCheck = StoreManager.Current.WorkflowStore.GetWorkflowDataById(workflowId);

            string taskType = null;

            if (jobToCheck != null)
            {
                taskType = TaskType.Job.ToString();
            }
            else if (workflowToCheck != null)
            {
                taskType = TaskType.Workflow.ToString();
            }

            if (taskType != null)
            {
                bool nextRetry = chkNextRetry.Checked;
                if (hfCheckType.Value == "RunOnce")
                {
                    ctCalendarSchedule.SelectedCalendarSchedule = null;
                    nextRetry = false;
                }

                GetSelectedMachines(jobDataList);

                SetJobsDetails(jobDataList, jobId, workflowId, taskType, nextRetry);

                var schedule = ctCalendarSchedule.SelectedCalendarSchedule;

                StoreManager.Current.JobStore.CreateJobs(jobDataList, schedule);

                phResult.Visible = true;

                ResetData();
            }
            else
            {
                txtResult.Text = string.Format(CommonString.HasBeenDeleted, (ddlJobNameList.SelectedIndex != 0) ? ddlJobNameList.SelectedItem.Text : ddlWorkflowList.SelectedItem.Text);
            }
        }

        protected void btnJobSelected_OnClick(object sender, EventArgs e)
        {
            SetViewMode("Job");
        }

        protected void btnWorkflowSelected_OnClick(object sender, EventArgs e)
        {
            SetViewMode("Workflow");
        }

        #endregion

        #region Private Method

        private void BindJobName()
        {
            var jobList = StoreManager.Current.JobDefinitionStore.GetAllJobDefinitions(-1, -1);

            ddlJobNameList.BindDataSource(jobList, "JobName", "JobId");

            ddlJobNameList.SelectedValue = JobId;

        }

        private void BindMachinePool()
        {
            divPoolMachineList.Visible = false;

            var machinePoolList = StoreManager.Current.MachineStore.GetAllMachinePool().ToList();

            ddlMachinePoolList.BindDataSource(machinePoolList, "PoolName", "PoolName");

            int poolId = 0;

            if (PoolId != null && int.TryParse(PoolId, out poolId))
            {
                rpMachineList.Visible = true;

                var pool = StoreManager.Current.MachineStore.GetMachinePoolInfoById(poolId);

                string poolName = string.Empty;

                if (pool != null)
                {
                    poolName = pool.PoolName;
                }

                ddlMachinePoolList.Text = poolName;

                divPoolMachineList.Visible = true;

                var machinelist = StoreManager.Current.MachineStore.GetMachinesByPoolId(poolId);

                rpMachineList.DataSource = machinelist;

                rpMachineList.DataBind();
            }
            else
            {
                ddlMachinePoolList.SelectedIndex = 0;
            }
        }

        private void BindWorkFlow()
        {
            var workflowList = StoreManager.Current.WorkflowStore.GetAllWorkflow(-1, -1);

            ddlWorkflowList.BindDataSource(workflowList, "WorkflowName", "WorkflowId");

            ddlWorkflowList.SelectedValue = WorkflowId;
        }

        private void SetJobsDetails(List<JobData> jobDataList, int jobId, int workflowId, string taskType, bool nextRetry)
        {
            TimeSpan timeOut = new TimeSpan();

            TimeSpan.TryParse(txtTimeOut.Text, out timeOut);

            int maxRetryTimes = 0;

            bool autoRetry = chkAutoRetry.Checked;

            if (autoRetry || nextRetry)
            {
                int.TryParse(txtRetryTimes.Text, out maxRetryTimes);
            }

            foreach (var job in jobDataList)
            {
                job.AbsoluteTimeout = timeOut;

                job.Description = txtDescription.Value;

                job.TaskId = jobId != 0 ? jobId : workflowId;

                job.Name = jobId != 0 ? ddlJobNameList.SelectedItem.Text : ddlWorkflowList.SelectedItem.Text;

                job.TaskType = taskType;

                job.StatusId = (int)JobStatus.Pending;

                job.UniqueId = Guid.NewGuid();

                job.CreatedDate = Helpers.Utils.CurrentServerUtcTime;

                job.IsDelete = false;

                job.AutoRetry = autoRetry;

                job.Retry = nextRetry;

                job.MaxRetry = maxRetryTimes;

                job.CreatedBy = CurrentUser;

            }
        }

        private void GetSelectedMachines(List<JobData> jobDataList)
        {
            List<string> machineList = new List<string>();

            for (int i = 0; i < rpMachineList.Items.Count; i++)
            {
                CheckBox checkBox = (CheckBox)rpMachineList.Items[i].FindControl("chkIsSelected");
                if (checkBox.Checked)
                {
                    Label machine = (Label)rpMachineList.Items[i].FindControl("lblMachineName");

                    machineList.Add(machine.Text);
                }
            }

            int machineCount = machineList.Count;

            for (int i = 0; i < machineCount; i++)
            {
                JobData job = new JobData();
                job.MachineName = machineList[i];
                jobDataList.Add(job);
            }
        }

        private void ResetData()
        {
            txtResult.Text = string.Empty;
            ddlJobNameList.SelectedIndex = 0;
            ddlWorkflowList.SelectedIndex = 0;
            txtDescription.InnerText = string.Empty;
            txtTimeOut.Text = string.Empty;
            txtRetryTimes.Text = string.Empty;
            chkAutoRetry.Checked = false;
            chkNextRetry.Checked = false;
        }

        private void ResetViewMode()
        {
            phJobName.Visible = false;

            phScheduleDetails.Visible = false;

            phScheduleSelect.Visible = false;

            phWorkflowName.Visible = false;

        }

        private void SetViewMode(string viewMode)
        {
            switch (viewMode)
            {
                case "Job":
                    phJobName.Visible = true;

                    phScheduleDetails.Visible = true;

                    phScheduleSelect.Visible = false;

                    break;
                case "Workflow":
                    phWorkflowName.Visible = true;

                    phScheduleDetails.Visible = true;

                    phScheduleSelect.Visible = false;

                    break;
                case "SelectItem":
                    phScheduleSelect.Visible = true;

                    break;
            }
        }

        #endregion

    }
}
